
package utils;


import java.util.ArrayList;
import java.util.Collections;

import genArchi.AbstractTask;
import genArchi.ComputeBox;
import org.eclipse.emf.common.util.EList;
import completeModel.Scheduler;
import procUseNB.LocalTask;
import procUseNB.ProcUseNB;
import procUseNB.ProcUseNBFactory;
import result.ResultFactory;
import result.Results;
import result.SchedulingResult;
import resultsWCRT.ResultsWCRT;
import resultsWCRT.ResultsWCRTFactory;
import techLL73.LL73;
import techLL73.TechLL73Factory;
import techResponseTimeNB.ResponseTimeRMNB;
import techResponseTimeNB.TechResponseTimeNBFactory;
import basicModelType1.BasicModelType1;
import basicModelType1.BasicModelType1Factory;
import basicModelType2.BasicModelType2;
import basicModelType2.BasicModelType2Factory;
import boundRMLL73.BoundRMLL73;
import boundRMLL73.BoundRMLL73Factory;


public class UtilsModelInstance {

	public static ProcUseNB createPUNB (EList<AbstractTask> l_task) {

		/**/
		ProcUseNB pu = ProcUseNBFactory.eINSTANCE.createProcUseNB();

		/**/
		for (AbstractTask t : l_task) {
			
			/* Create local tasks, and set attributes */
			LocalTask lt = ProcUseNBFactory.eINSTANCE.createLocalTask();
			lt.setPeriod(t.getPeriod());
			lt.setWcet(t.getWcet());
			
			/* Add to list of tasks*/
			pu.getTasks().add(lt);
		}

		return pu;

	} // createPUNB

	public static BoundRMLL73 createBound_RM_LL73 (int nb_tasks) {

		/**/
		BoundRMLL73 bound = BoundRMLL73Factory.eINSTANCE.createBoundRMLL73();

		/**/
		bound.setNb_Tasks(nb_tasks);

		return bound;

	} // createBound_RM_LL73

	public static LL73 createTechRMLL73 (BoundRMLL73 b, ProcUseNB u) {

		/**/
		LL73 t = TechLL73Factory.eINSTANCE.createLL73();

		/**/
		t.setBoundLL73(b);
		t.setPU(u);

		/**/

		return t;

	} // createTechnicRMLL73

	public static BasicModelType1 createBasicModelType1 (Scheduler scheduler , EList< String> l_id, EList<Integer> l_wcet, EList<Integer> l_period, EList<Integer> l_priority) {

		/**/
		BasicModelType1 basicModel = BasicModelType1Factory.eINSTANCE.createBasicModelType1();

		/**/
		basicModel.setScheduler(scheduler);
		
		/**/
		for ( int i = 0; i < l_id.size() ; i++) {
			
			/**/
			basicModelType1.LocalTask lt = BasicModelType1Factory.eINSTANCE.createLocalTask();
			lt.setId(l_id.get(i));
			lt.setPeriod(l_period.get(i));
			lt.setWcet(l_wcet.get(i));
			lt.setPriority(l_priority.get(i));
			
			basicModel.getTasks().add(lt);
		}

		return basicModel;

	} // createBasicModelType1

	public static BasicModelType2 createBasicModelType2 (Scheduler scheduler , EList< String> l_id, EList<Integer> l_wcet, EList<Integer> l_period, EList<Integer> l_deadline, EList<Integer> l_priority) {

		/**/
		BasicModelType2 bmt2 = BasicModelType2Factory.eINSTANCE.createBasicModelType2();

		/**/
		bmt2.setScheduler(scheduler);
		
		for (int i = 0; i < l_id.size() ; i++) {
			
			/**/
			basicModelType2.LocalTask lt = BasicModelType2Factory.eINSTANCE.createLocalTask();
			lt.setId(l_id.get(i));
			lt.setPeriod(l_period.get(i));
			lt.setWcet(l_wcet.get(i));
			lt.setDeadline(l_deadline.get(i));
			lt.setPriority(l_priority.get(i));
			
			/**/
			bmt2.getTasks().add(lt);
			
		}


		/**/
		return bmt2;
	} //createBasicModelType2

	public static ResponseTimeRMNB createResponseTimeRMNB (EList< AbstractTask> l_tasks) {

		/**/
		ResponseTimeRMNB rt = TechResponseTimeNBFactory.eINSTANCE.createResponseTimeRMNB();

		/**/
		for (AbstractTask t : l_tasks) {
			
			/**/
			techResponseTimeNB.LocalTask lt = TechResponseTimeNBFactory.eINSTANCE.createLocalTask();
			lt.setId(t.getId());
			lt.setPeriod(t.getPeriod());
			lt.setWcet(t.getWcet());
			lt.setPriority(t.getPriority());
			lt.setDeadline(t.getDeadline());
			
			/**/
			rt.getTasks().add(lt);
		}

		return rt; 

	} // createResponseTime_RM_NB

	public static void createSchedulingResult (ComputeBox current, Results r) {

		SchedulingResult sr = null;
		
		for (ComputeBox box : current.getRoot().getComputeBoxes()) {

			if ((box instanceof SchedulingResult) && (((SchedulingResult)box).getResult() == r)) {
				
				sr = (SchedulingResult)box;
			}				
		}
		
		if  (sr == null) {
			sr = ResultFactory.eINSTANCE.createSchedulingResult();
			sr.setResult(r);
			linkComputeBox(current, sr, false);
		}
		/**/
		else {
			linkComputeBox(current, sr, true);	
		}
		


	} //createSchedulingResult()


	public static ResultsWCRT createResultsWCRT () {
		
		/**/
		ResultsWCRT r_wcrt = ResultsWCRTFactory.eINSTANCE.createResultsWCRT();
		
		/**/
		return r_wcrt;
		
	} //ResultsWCRT()
	
	public static void linkComputeBox (ComputeBox current, ComputeBox next, boolean exists) {

		if (!exists) {

			/* Set Root attribute & add to Root list*/
			next.setRoot(current.getRoot());
			next.getRoot().getComputeBoxes().add(next);
		}

		/* Graph paths */
		current.getNext().add(next);
		next.getPrevious().add(current);

	} // linkComputeBox () 


	public static <T extends ComputeBox> ComputeBox lookForComputeBox (ComputeBox current, Class<T> className) {


		/**/
		for (ComputeBox box : current.getRoot().getComputeBoxes()) {

			if (box.getClass() == className) {
				return box;
			}				
		}

		return null;

	} // lookForComputeBox ()

	public static void orderByPriority (EList<AbstractTask> l_tasks) {
		
		/**/
		ArrayList<AbstractTask> l_temp = new ArrayList<AbstractTask> ();
		for (AbstractTask at : l_tasks) {
			l_temp.add(at);
		}

		/**/
		Collections.sort(l_temp, new PriorityComparator());
		
		/**/
		l_tasks.clear();
		for (AbstractTask at : l_temp) {
			l_tasks.add(at);
		}
	}
} // class UtilsModelInstance